<?php

/**
 * Created by PhpStorm.
 * User: longli
 * VX: isa1589518286
 * Date: 2021/01/25
 * Time: 13:58
 * @link http://www.lmterp.cn
 */
namespace app\common\service\logistics;

use app\common\library\Tools;
use app\common\model\ChannelExpress;
use app\common\model\PurchaseTrack;
use app\common\model\WarehouseAllot;
use app\common\service\BaseService;

/**
 * 快递100获取物流信息
 * Class Kuaidi100
 * @package app\common\service\logistics
 * @link https://api.kuaidi100.com/document/5f0ffa8f2977d50a94e1023c.html
 */
class Kuaidi100 extends BaseService
{

    /**
     * 请求地址
     * @var string
     */
    protected $url = 'http://poll.kuaidi100.com/poll/query.do';

    /**
     * 响应体
     * @var array
     */
    protected $data = [];

    /**
     * 错误信息
     * @var array
     */
    protected $error = [];

    /**
     * 订单id
     * @var array
     */
    protected $ids = [];

    public function __construct($ids)
    {
        $this->ids = is_array($ids) ? $ids : explode(',', $ids);
    }

    /**
     * 执行获取物流信息
     * @param string $code 快递编号
     * @param string $trackNum 追踪号
     * @param string $phone 电话号码
     * @return bool
     * @date 2021/02/04
     * @author longli
     */
    protected function get($code, $trackNum, $phone = '')
    {
        if(!$this->validateRequest($code, $trackNum, $phone)) return false;
        $response = Tools::curlPost($this->url, $this->getSign($code, $trackNum, $phone));
        if(!$response['status'])
        {
            $this->error[] = "服务器请求不通";
            return false;
        }
        // 验证响应信息
        if(!$this->validateResponse($response['data'])) return false;
        return true;
    }

    /**
     * 采购单物流信息
     * @return bool
     * @date 2021/02/04
     * @author longli
     */
    public function purchase()
    {
        foreach(PurchaseTrack::with([
            'express' => function($query)
            {
                $query->field(['express_id', 'track_code']);
            },
            'purchase' => function($query)
            {
                $query->field(['purchase_id', 'phone']);
            }
        ])->whereIn("track_id", $this->ids)->select() as $track)
        {
            if(!$this->get($track->express->track_code, $track->track_num, $track->purchase->phone)) continue;
            $data = $this->getData();
            $track->track_status = $this->mapping($data['state']);
            $track->track_info = json_encode($data);
            $track->save();
        }
        return true;
    }

    /**
     * 调拨单物流信息
     * @date 2021/03/18
     * @author longli
     */
    public function allot()
    {
        foreach(WarehouseAllot::with([
            'express' => function($query)
            {
                $query->field(['express_id', 'track_code']);
            },
            'wout' => function($query)
            {
                $query->field(['warehouse_id', 'phone']);
            }
        ])->whereIn("allot_id", $this->ids)->select() as $allot)
        {
            if(!$this->get($allot->express->track_code, $allot->track_num, $allot->wout->phone)) continue;
            $data = $this->getData();
            $allot->track_status = $this->mapping($data['state']);
            $allot->track_info = json_encode($data);
            $allot->save();
        }
        return true;
    }

    /**
     * 计算请求参数
     * @param string $code 快递编号
     * @param string $trackNum 追踪号
     * @param string $phone 电话号码
     * @return string
     * @date 2021/02/04
     * @author longli
     */
    protected function getSign($code, $trackNum, $phone = '')
    {
        $param = [
            'com' => $code,
            'num' => $trackNum,
            'phone' => $phone,
            'resultv2' => '1',
        ];
        $post["customer"] = config('param.kuaidi100_api_customer');
        $post["param"] = json_encode($param);
        $sign = md5($post["param"] . config('param.kuaidi100_api_key') . $post["customer"]);
        $post["sign"] = strtoupper($sign);
        return http_build_query($post);
    }

    /**
     * 验证请求参数
     * @param string $code 快递编号
     * @param string $trackNum 追踪号
     * @param string $phone 电话号码
     * @return bool
     * @date 2021/02/04
     * @author longli
     */
    protected function validateRequest($code, $trackNum, $phone = '')
    {
        if(in_array($code, ['shunfeng', 'shunfengkuaiyun', 'nsf', 'shunfenghk']) && empty($phone))
        {
            $this->error[] = "顺丰快递（收件/寄件）人（手机/电话）号码必填一个";
            return false;
        }
        return true;
    }

    /**
     * 验证响应信息
     * @param string $response 响应信息
     * @return bool
     * @date 2021/02/04
     * @author longli
     */
    protected function validateResponse(& $response)
    {
        $this->data = $response = json_decode($response, true);
        if(isset($response['status']) && $response['status'] == 200) return true;
        if(isset($response['returnCode']) && $response['returnCode'] != 200)
        {
            $this->error[] = $response['message'];
            return false;
        }
        return false;
    }

    /**
     * 映射关系
     * @param int $n 快递100状态码
     * @return int
     * @date 2021/02/04
     * @author longli
     */
    protected function mapping($n)
    {
        return isset(ChannelExpress::$TRACK_STATUS[$n])
            ? $n
            : ChannelExpress::TRACK_STATUS_NONE;
    }

    public function getData()
    {
        return $this->data;
    }

    public function getError()
    {
        return $this->error;
    }
}